;(function(){
	
	// fso不存在 rename()，只有通过 move() 来完成。
	function renName(){}
	
	/**
	 * @class $$.fs.File
	 */
	$$.fs.File = function(){
		
		/**
		 * 根据文件的MIME（content-type）类型，返回文件的扩展名。
		 * @param  {String} contentType
		 * @return {String} null表示为不能识别该Content-Type。
		 */
		this.setMIME = function(contentType){
	        switch(contentType){
                case "application/msword" :
                    return ".doc";break;			
                case "application/pdf" :
                    return ".pdf";break;			
                case "application/vnd.ms-excel" :
                    return ".xls";break;			
                case "application/vnd.ms-powerpoint" :
                    return ".ppt";break;			
                case "application/x-javascript" :
                    return ".js";break;			
                case "application/x-shockwave-flash" :
                    return ".swf";break;			
                case "application/xhtml+xml" :
                    return ".xhtml";break;			
                case "application/zip" :
                    return ".zip";break;			
                case "application/msaccess" :
                    return ".mdb";break;			
                case "audio/midi" :
                    return ".mid";break;			
                case "audio/mpeg" :
                    return ".mp3";break;			
                case "audio/x-aiff" :
                    return ".aif";break;			
                case "audio/x-mpegurl" :
                    return ".m3u";break;			
                case "application/vnd.rn-realmedia" :
                case "audio/x-pn-realaudio" :
                    return ".rm";break;			
                case "audio/x-pn-realaudio-plugin" :
                    return ".rpm";break;			
                case "audio/x-realaudio" :
                    return ".ra";break;			
                case "audio/wav" :
                    return ".wav";break;			
                case "image/bmp" :
                    return ".bmp";break;			
                case "image/gif" :
                    return ".gif";break;		
                case "image/jpg" :
                case "image/jpeg" :
                case "image/pjpeg" :
                    return ".jpg";break;
                case "image/x-png":
                case "image/png" :
                    return ".png";break;			
                case "image/tiff" :
                    return ".tiff";break;			
                case "image/vnd.wap.wbmp" :
                    return ".wbmp";break;		
                case "text/css" :
                    return ".css";break;			
                case "text/html" :
                    return ".html";break;			
                case "text/plain" :
                    return ".txt";break;			
                case "text/richtext" :
                    return ".rtx";break;			
                case "text/rtf" :
                    return ".rtf";break;			
                case "text/xml" :
                    return ".xml";break;			
                case "video/mpeg" :
                    return ".mpeg";break;			
                case "audio/x-ms-wma" :
                    return ".wma";break;			
                case "video/quicktime" :
                    return ".mov";break;			
                case "video/vnd.mpegurl" :
                    return ".mxu";break;			
                case "video/x-msvideo" :
                    return ".avi";break;			
                case "video/x-sgi-movie" :
                    return ".movie";break;	
                case "application/octet-stream" :
                default :
                    return null; // 分不清什么类型，返回null。
            } 
        }
		
	}
})();

/** 
 * 打开文件，读取其内容，返回文本的格式。
 * @static
 * @param	{String}	path		文件路径
 * @param	{Boolean}	isMapPath	是否送入相对路径。True的话把虚拟路径还原为真实的磁盘路径。
 * @return	{String} 				文本内容
 */
$$.fs.File.read = function(path){
	with(new ActiveXObject("Adodb.Stream")){
        type = 2;
        mode = 3;
        charset = "utf-8";
        try {
            open();
            loadFromFile(path);
            return readText();
        }catch (e){
            throw e;
        }finally{
            close();
        }
    }
}

/**
 * 将数据保存到磁盘上。可支持文本数据和二进制数据。
 * @static
 * @param 	{String} 	data 		要写入的数据，可以是二进制对象。
 * @param 	{String} 	path 		文件路径。
 * @param 	{Boolean} 	isBinary	是否为二进制数据。
 * @param 	{Boolean} 	isMapPath	是否送入相对路径。True的话把虚拟路径还原为真实的磁盘路径。
 * @return 	{Boolean} 	True		表示操作成功。
 */
$$.fs.File.write = function(data, path, isBinary, chartset){
    with(new ActiveXObject("Adodb.Stream")){
        type = isBinary ? 1 : 2;
        if (!chartset && !isBinary)
			charset = "utf-8";
        if (chartset)
			charset = "GB2312";
        try {
			open();
			if(!isBinary){
				writeText(data);
			}else{
				write(data);
			} 
			saveToFile(path, 2);
			return true;
        }catch(e){
			throw e;
        } finally {
			close();
        }
    }
    
    return true;
}

var noType = /(?:\|?exe\|?)|(?:\|?dll\|?)|(?:\|?jpe?g\|?)|(?:\|?gif\|?)/i;
// 使用setTimeout的好处是可随时中止。
var EasySR = {

	/**
	 * @param {String} sPath 对哪个目录进行搜索，即“目录路径”。
	 * @param {RegExp} sExt 扩展名
	 * @param {String} sReg 搜索的内容。
	 * @param {String} sRep 替换的内容（可选的）。
	 * @param {String} sIG 正则的第二个参数。
	 * @param {Boolean} sReplace 是否也替换呢？
	 * @param {Boolean} sCopy 替换后应该是直接覆盖或则备份。
	 * @param {Boolean} sSub 是否包括子目录。
	 */
	matchFile : function(sPath, sExt, sReg, sRep, sIG, sReplace, sCopy, sSub){
		if (!sPath || !sExt)return;
		if (noType.test(sExt)){
			alert('Only accept the text of the types of files!');
			return;
		}
		
		 btnStart.style.display	= 'none'
		,btnStop.style.display	= 'inline-block'
		,cmd.innerHTML			= '正在搜索中……'
		,list.innerHTML			= '<select size="10"><option>搜索文件中……</option></select>';
		
		var 
			 fso = new ActiveXObject("Scripting.FileSystemObject")
			,aP  = [sPath]
			,aF  = []	// 命中的文件列表
			,aM  = []
			,aC  = []	// chartset
			,ext = new RegExp('\.(?:' + sExt + ')$', 'i') // 扩展名的正则
			,rt  = new RegExp(sReg, 'i')
			,r   = new RegExp(sReg, sIG)
			,iL 		= 0
			,ipp 		= 0
			,iTimerSF	= 0
			,iTimerMF	= 0;
			
		// stop 
		btnStop.onclick = function(){
			if (iTimerSF)
				window.clearTimeout(iTimerSF);
			if (iTimerMF)
				window.clearTimeout(iTimerMF);

			btnStart.style.display = 'inline-block';
			btnStop.style.display  = 'none';
		};
		// search files
		// 先根据输入的条件，搜索符合文件名要求的文件，
		// 再匹配内容。
		var innerSF = function(){
			if (aP.length == 0){
				// 搜索结束
				 iL 				= aF.length
				,fcount.innerHTML 	= iL + ' files waiting for match'
				,cmd.innerHTML 		= '匹配的结果有：'
				,list.innerHTML	 	= '<select size="10"><option>' + aF.join('</option><option>') + '</option></select>';
				
				if(iTimerSF){
					window.clearTimeout(iTimerSF);
				}
				// 搜索文件而已
				if(!sReg){
					 btnStart.style.display = 'inline-block'
					,btnStop.style.display 	= 'none'
					,cmd.innerHTML 			= 'Mission completed! '
					,msg.innerHTML 			= 'Search files: ' + aF.length
					,aF = null;
				}else{
					iTimerMF = window.setTimeout(innerMF);
				}
				return;
			}
			var sPath = aP.shift();
			
			if (!fso.FolderExists(sPath)){
				iTimerSF = window.setTimeout(arguments.callee);
				return;
			}
			msg.innerHTML = sPath;
			
			var
				 f	= fso.GetFolder(sPath)
				,fs = new Enumerator(f.files)		// 遍历文件
				,sf = new Enumerator(f.SubFolders)	// 遍历目录
				,fileObj;							// 文件对象

			while(!fs.atEnd()){
				fileObj = fs.item();
				if (ext.test(fileObj.path)){
					aF.push(fileObj);
				}
				ext.lastIndex = 0;
				
				fs.moveNext();
			}

//			aFT = null; ？？
			if (sSub == 'fs'){
				var aTmp = [];
				for (; !sf.atEnd(); sf.moveNext()) {
					aTmp.push(sf.item());
				}
				aP = aTmp.slice(0).concat(aP);
				aTmp = null;
			}
			iTimerSF = window.setTimeout(arguments.callee);
		}
		// match files
		var innerMF = function(){
			if (ipp == iL) {
				
				 btnStart.style.display	= 'inline-block'
				,btnStop.style.display	= 'none';
				
				if (iTimerMF)
					window.clearTimeout(iTimerMF);
				aF = aM = null;
				return;
			}
			var 
				 sF = aF[ipp]
				,ifsize
				,oFile;
				
			ipp++;
			
			if(!fso.FileExists(sF)){
				iTimerMF = window.setTimeout(arguments.callee);
				return;
			}
			
			ifsize = parseInt(fso.GetFile(sF).size, 10) / 1024 / 1024;
			
			if(ifsize <= 5){// set file size less than 5m
				 msg.innerHTML 	= sF
				,oFile			= $$.fs.File.read(sF)
				,sFile			= oFile[0]
				,sCharset		= oFile[1];
				
				if(rt.test(sFile)){
					if (sReplace == 'replace'){
						if (sCopy == 'copy'){
							EasySR.saveFile(sF + '.EasySR', sFile, sCharset);
						}
						EasySR.saveFile(sF, sFile.replace(r, sRep), sCharset);
					}
					rt.lastIndex = 0;
					aM.push(sF);
					aC.push(sCharset);
				}
			}
			
			iTimerMF = window.setTimeout(arguments.callee);
		}
		// start
		iTimerSF = window.setTimeout(innerSF);
	}
}

/**
 * @private
 * @param {String} str
 * @return {Shell.Application}
 */
function showFolderPickuper(str){
	var objFolder = new ActiveXObject("Shell.Application").BrowseForFolder(
		0
		,str || "请选择一个目录。"
		,0
		,0x11
	);
	return objFolder ? objFolder.Self.Path : '';
}

﻿$$.disk = {

//function folderHelper(path, onfile_Fn, onfolder_Fn) {
//	var fso = new ActiveXObject("Scripting.FileSystemObject");
//		
//	if (fso.FolderExists(path)){
//		search(fso.GetFolder(path));
//	}
//	// __Search()
//	function search(folder){
//		for (var e = new Enumerator(folder.SubFolders); !e.atEnd(); e.moveNext()) {
//			var item = e.item();
//			if (typeof onfolder_Fn === "function")
//				onfolder_Fn(item, fso);
//			if (recursive){
//				arguments.callee(item);
//			}
//		}
//		for (var e = new Enumerator(folder.Files); !e.atEnd(); e.moveNext()) {
//			if (typeof onfile_Fn === "function"){
//				onfile_Fn(e.item(), fso);
//			}
//		}
//	}
//}	
	/**
	 * @param {String} folder
	 * @param {Function} fn
	 */
	getFlatFlies : function(folder, isRecursive, fn, scope){
	    var  
	         fso    = new ActiveXObject("Scripting.FileSystemObject")
	        ,target = fso.getFolder(folder);	
	        
	    if(!fn || typeof(fn) != 'function'){
	    	throw "该函数期待一个合法函数的参数！";
	    }
	    
	    function getFiles(folderObj){
	        var fileObj, i = 0;
	        with(new Enumerator(folderObj.Files /* 列出所有文件 */)){
	            while (!atEnd()){
	                fileObj = item();
//	                if(fileObj.Name.split('.').pop().indexOf('js') != -1){
//	                    arr.push(fileObj.Path);
//	                }
	                fn.call(scope, fileObj, folderObj, i++);
	                fileObj = null;
	                moveNext();
	            }		
	        } 
	    }
	    // 本目录下的文件
	    getFiles(target);
	    // 子目录下所有的文件
	    if(isRecursive){
		    ;(function(items){
		        var folderObj;
		        with(new Enumerator(items)){
		            while (!atEnd()){
		                folderObj = item();
		                getFiles(folderObj);
		                
		                if(folderObj.subFolders.Count > 0){
		                    arguments.callee(folderObj.subFolders); //　递归
		                }
		                folderObj = null;
		                moveNext();
		            }		
		        }      
		    })(target.SubFolders);  
	    }
	    
	    return true;
	}
    
	,base64EncodeText: function (TextStr) {
		var xml_dom = new ActiveXObject("MSXML2.DOMDocument");
		var ado_stream = new ActiveXObject("ADODB.Stream");
		var tmpNode = xml_dom.createElement("tmpNode");
		
		tmpNode.dataType = "bin.base64";
		ado_stream.Charset = "gb2312";
		ado_stream.Type = 2;// 1=adTypeBinary 2=adTypeText
		if (ado_stream.state == 0) {// 0=adStateClosed 1=adStateOpen
			ado_stream.Open();
		}
		ado_stream.WriteText(TextStr);
		ado_stream.Position = 0;
		ado_stream.Type = 1;// 1=adTypeBinary 2=adTypeText
		tmpNode.nodeTypedValue = ado_stream.Read(-1);// -1=adReadAll
		ado_stream.Close();
		return tmpNode.text;
	}    
	
};

/**
 * 自动适应编码类型http://www.codeproject.com/KB/scripting/Exsead7.aspx
 * @param {String} filename
 * @return {String}
 */ 
$$.disk.toString = function(filename, sCharset) {
	var fileContent, stream = new ActiveXObject('adodb.stream');

	with(stream){
		type = 2;// 1－二进制，2－文本
		mode = 3;// 1－读，2－写，3－读写
		open();
	
		if (!sCharset) {
			try{
				stream.charset = "437"; // why try, cause some bug now
			}catch(e){}
			loadFromFile(filename);
			
			// get the BOM(byte order mark) or escape(ReadText(2)) is fine?
			switch (escape(readText(2).replace(/\s/g, ''))) {
				case "%3Ca" :
				case "%3Cd" :
				case "%3C%3F" :
				case "%u2229%u2557" :	// 0xEF,0xBB => UTF-8
					sCharset = "UTF-8";
					break;
				case "%A0%u25A0" :		// 0xFF,0xFE => Unicode
				case "%u25A0%A0" :		// 0xFE,0xFF => Unicode big endian
					sCharset = "Unicode";
					break;
				default :
					// 判断不出来就使用GBK，这样可以在大多数情况下正确处理中文
					sCharset = "GBK";	
//					close();
					// 用使用“系统默认编码”
					// { Read: 1, Write: 2, Append: 8 }
//					with(new ActiveXObject("Scripting.FileSystemObject").openTextFile(filename, 1)){
//						fileContent = readAll();
//						close();
//					}
//					fileContent = new String(fileContent);
//					fileContent.charset = 'SystemDefault';
//					return fileContent;
					break;
			}
			close();
			open();
		}
		charset = sCharset;
		loadFromFile(filename);
		fileContent = new String(readText());
		fileContent.charset = sCharset;
		close();
	}
	return fileContent;
}

